<template>
  <div class="container">
    <!-- 固定导航 -->
    <van-nav-bar fixed left-arrow @click-left="$router.back()" title="人工智障"></van-nav-bar>

    <!-- 聊天主体区域 -->
    <div class="chat-list" ref="chatList">
      <!-- 左侧是机器人小智 -->
      <div class="chat-item"
           v-for="( item,index) in list"
           :key="index"
           :class="item.name ==='xz' ? 'left' : 'right'">
        <template v-if="item.name === 'xz'">
          <van-image fit="cover" round src="https://img.yzcdn.cn/vant/cat.jpeg"/>
          <div class="chat-pao">{{ item.msg }}</div>
        </template>
        <template v-else>
          <!-- 右侧是当前用户 -->
          <div class="chat-item right">
            <div class="chat-pao">{{ item.msg }}</div>
            <van-image fit="cover" round :src="user.photo"/>
          </div>
        </template>
      </div>
    </div>

    <!-- 对话区域 -->
    <div class="reply-container van-hairline--top">
      <van-field v-model.trim="word" placeholder="说点什么...">
        <span @click="send()" slot="button" style="font-size:12px;color:#999">提交</span>
      </van-field>
    </div>
  </div>
</template>

<script>

  import { reqGetUserProfile } from '@/api/user.js'

  // 引入websocket依赖包
  import io from 'socket.io-client'

  export default {
    name: 'UserChat',
    data () {
      return {
        word: '',
        // 用户信息
        user: {},
        // 对话记录
        list: [
          { name: 'xz', msg: '你好，我是无所不知的智障！', timestamp: Date.now() },
          { name: 'me', msg: '夏钦, 今天下雨吗？', timestamp: Date.now() },
          { name: 'me', msg: '快帮我查查', timestamp: Date.now() },
          { name: 'xz', msg: '今天不下雨', timestamp: Date.now() }
        ],
        // websocket连接对象
        websocket: null
      }
    },
    created () {
      this.loadUserProfile()
      // 页面初始化连接websocket
      this.initWebSocket()
    },
    methods: {

      // 获取用户个人信息
      async loadUserProfile () {
        const res = await reqGetUserProfile()
        this.user = res.data.data
      },

      send () {
        if (this.word === '') {
          return
        }

        // 发送消息
        this.websocket.emit('message', {
          msg: this.word,
          timestamp: Date.now()
        })
        this.list.push({
          name: 'me',
          msg: this.word,
          timestamp: Date.now()
        })

        // 重制输入框
        this.word = ''

        this.$nextTick(() => {
          this.$refs.chatList.scrollTop = this.$refs.chatList.scrollHeight
        })
      },

      // 连接websocket(固定写法)
      initWebSocket () {
        this.websocket = io('http://localhost:8888')
        // 连接的处理逻辑
        this.websocket.on('connect', () => {
          // vant轻提示（原生可以使用confirm和alert提示）
          this.$toast('已连接服务端')
        })
        // 处理服务器发送的消息（形参自定义）
        this.websocket.on('message', ({ msg, timestamp }) => {
          // 规定发送的内容
          this.list.push({
            name: 'xz',
            msg: msg,
            timestamp
          })
        })

        /*
            nextTick方法是将回调函数延迟在下一次dom更新数据后调用，也就是当数据更新了，
            然后在dom中渲染后，就会自动执行nextTick函数。

            this.$refs是一个对象，持有当前组件中注册过 ref特性的所有 DOM 元素和子组件实例；
            $refs只有在组件渲染完成后才填充，在初始渲染的时候不能访问它们，并且它是非响应式的，
            因此不能用它在模板中做数据绑定
         */
        // 处理滚动条
        // 每次数据更新后 重新设置 chatlist元素的scrollTop值scrollTop是可读可写的
        // scrollHeight 如果元素没有滚动条,获取到的就是元素的高度
        // scrollHeight 如果元素有了滚动条,获取到的是元素的高度+滚出的高度
        this.$nextTick(() => {
          this.$refs.chatList.scrollTop = this.$refs.chatList.scrollHeight
        })
      }
    }
  }
</script>

<style lang="scss" scoped>
  .container {
    height: 100%;
    width: 100%;
    position: absolute;
    left: 0;
    top: 0;
    box-sizing: border-box;
    background: #fafafa;
    padding: 46px 0 50px 0;

    .chat-list {
      height: 100%;
      overflow-y: scroll;

      .chat-item {
        padding: 10px;

        .van-image {
          vertical-align: top;
          width: 40px;
          height: 40px;
        }

        .chat-pao {
          vertical-align: top;
          display: inline-block;
          min-width: 40px;
          max-width: 70%;
          min-height: 40px;
          line-height: 38px;
          border: 0.5px solid #c2d9ea;
          border-radius: 4px;
          position: relative;
          padding: 0 10px;
          background-color: #e0effb;
          word-break: break-all;
          font-size: 14px;
          color: #333;

          &::before {
            content: "";
            width: 10px;
            height: 10px;
            position: absolute;
            top: 12px;
            border-top: 0.5px solid #c2d9ea;
            border-right: 0.5px solid #c2d9ea;
            background: #e0effb;
          }
        }
      }
    }
  }

  .chat-item.right {
    text-align: right;

    .chat-pao {
      margin-left: 0;
      margin-right: 15px;

      &::before {
        right: -6px;
        transform: rotate(45deg);
      }
    }
  }

  .chat-item.left {
    text-align: left;

    .chat-pao {
      margin-left: 15px;
      margin-right: 0;

      &::before {
        left: -5px;
        transform: rotate(-135deg);
      }
    }
  }

  .reply-container {
    position: fixed;
    left: 0;
    bottom: 0;
    height: 44px;
    width: 100%;
    background: #f5f5f5;
    z-index: 9999;
  }
</style>
